// PovRayMakeMovie.cpp : implementation file
//

#include "stdafx.h"
#include "ProteinVista.h"
#include "MainFrm.h"
#include "PovRayMakeMovie.h"


// CPovRayMakeMovie dialog

IMPLEMENT_DYNAMIC(CPovRayMakeMovie, CDialog)

CPovRayMakeMovie::CPovRayMakeMovie(CWnd* pParent /*=NULL*/)
	: CDialog(CPovRayMakeMovie::IDD, pParent)
{

}

CPovRayMakeMovie::~CPovRayMakeMovie()
{
}

void CPovRayMakeMovie::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST_IMAGE_LIST, m_listCtrlImageList);
}


BEGIN_MESSAGE_MAP(CPovRayMakeMovie, CDialog)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_IMAGE_LIST, &CPovRayMakeMovie::OnLvnItemchangedListImageList)
	ON_BN_CLICKED(IDC_BUTTON_MAKE_MOVIE, &CPovRayMakeMovie::OnBnClickedButtonMakeMovie)
	ON_BN_CLICKED(IDC_BUTTON_DELETE, &CPovRayMakeMovie::OnBnClickedButtonDelete)
	ON_BN_CLICKED(IDC_BUTTON_VIEW_MOVIE, &CPovRayMakeMovie::OnBnClickedButtonViewMovie)
END_MESSAGE_MAP()


// CPovRayMakeMovie message handlers

void CPovRayMakeMovie::OnLvnItemchangedListImageList(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	// TODO: Add your control notification handler code here
	*pResult = 0;
}

void CPovRayMakeMovie::OnBnClickedButtonMakeMovie()
{
	int nItem = -1;
	POSITION pos = m_listCtrlImageList.GetFirstSelectedItemPosition();
	if (pos != NULL)
	{
		nItem = m_listCtrlImageList.GetNextSelectedItem(pos);
	}

	if ( nItem != -1 )
	{
		//	if selected.
		CString strMovieIniFilePath = m_strArrayINIFilename[nItem];

		TCHAR buff[1024*10];
		GetPrivateProfileString(_T("Movie"), _T("FileName"),_T(""), buff , MAX_PATH, strMovieIniFilePath);
		CString filenameINI(buff);

		GetPrivateProfileString(_T("Movie"), _T("FilenameFormat"),_T(""), buff , MAX_PATH, strMovieIniFilePath);
		CString filenameFormatINI(buff);

		GetPrivateProfileString(_T("Movie"), _T("FinalMoviePath"),_T(""), buff , MAX_PATH, strMovieIniFilePath);
		CString strFinalMoviePath(buff);

		INT32	movieWidth = GetPrivateProfileInt(_T("Movie"), _T("Width"), 320, strMovieIniFilePath);
		INT32	movieHeight = GetPrivateProfileInt(_T("Movie"), _T("Height"), 200, strMovieIniFilePath);
		INT32	movieFps = GetPrivateProfileInt(_T("Movie"), _T("Fps"), 10, strMovieIniFilePath);
		INT32	movieNumImages = GetPrivateProfileInt(_T("Movie"), _T("NumImages"), 0, strMovieIniFilePath);

		CStringArray	strArrayFilename;
		for ( int i = 0 ; i < movieNumImages; i++ )
		{
			CString strImageFilename;
			strImageFilename.Format(filenameFormatINI, ((CProteinVistaApp*)AfxGetApp())->m_strBaseScriptMovie+_T("Images\\")+filenameINI, i );

			strArrayFilename.Add(strImageFilename);
		}

		CSTLIntArray arrayFrame;
		GetPrivateProfileSection(_T("Frames"), buff, 1024*10, strMovieIniFilePath);
		TCHAR * buffFrames = buff;
		while(buffFrames[0] != NULL)
		{
			arrayFrame.push_back(atoi(buffFrames));
			buffFrames += (_tcslen(buffFrames)+1);
		}

		//	
		AfxGetApp()->DoWaitCursor(1);		// 1->>display the hourglass cursor
		CString strFinalMoviePathResult;
		HRESULT hr = ((CMainFrame*)AfxGetMainWnd())->MakeMovieWithImages(strFinalMoviePath, strArrayFilename, arrayFrame, movieWidth, movieHeight, movieFps , strFinalMoviePathResult );
		AfxGetApp()->DoWaitCursor(-1);		
		if ( SUCCEEDED(hr))
		{
			ShellExecute(NULL, NULL,  strFinalMoviePathResult , NULL, NULL, SW_SHOWNORMAL );
		}
	}

	OnCancel();
}

void CPovRayMakeMovie::OnBnClickedButtonViewMovie()
{
	int nItem = -1;
	POSITION pos = m_listCtrlImageList.GetFirstSelectedItemPosition();
	if (pos != NULL)
	{
		nItem = m_listCtrlImageList.GetNextSelectedItem(pos);
	}

	if ( nItem != -1 )
	{
		ShellExecute(NULL, NULL,  m_strArrayMovieFilename[nItem] , NULL, NULL, SW_SHOWNORMAL );
	}

	OnCancel();
}

void CPovRayMakeMovie::OnBnClickedButtonDelete()
{
	if ( IDYES == AfxMessageBox("Delete all relative files? Movie file is not deleted.", MB_YESNOCANCEL ) )
	{
		int nItem = -1;
		POSITION pos = m_listCtrlImageList.GetFirstSelectedItemPosition();
		if (pos != NULL)
		{
			nItem = m_listCtrlImageList.GetNextSelectedItem(pos);
		}

		if ( nItem != -1 )
		{

			//	delete *.pov
			//	delete *.png
			//	delete 1 ini files.

			CString strMovieIniFilePath = m_strArrayINIFilename[nItem];
			INT32	movieNumImages = GetPrivateProfileInt(_T("Movie"), _T("NumImages"), 0, strMovieIniFilePath);

			TCHAR buff[1024*10];
			GetPrivateProfileString(_T("Movie"), _T("FileName"),_T(""), buff , MAX_PATH, strMovieIniFilePath);
			CString filenameINI(buff);

			GetPrivateProfileString(_T("Movie"), _T("FilenameFormat"),_T(""), buff , MAX_PATH, strMovieIniFilePath);
			CString filenameFormatINI(buff);

			//
			//	delete rotation.pov, rotation.ini
			//
			DeleteFile(((CProteinVistaApp*)AfxGetApp())->m_strBaseScriptMovie+_T("Images\\")+filenameINI+_T(".pov"));
			DeleteFile(((CProteinVistaApp*)AfxGetApp())->m_strBaseScriptMovie+_T("Images\\")+filenameINI+_T(".ini"));

			for ( int i = 0 ; i < movieNumImages; i++ )
			{
				//	delete png.
				CString strImageFilename;
				strImageFilename.Format(filenameFormatINI, ((CProteinVistaApp*)AfxGetApp())->m_strBaseScriptMovie+_T("Images\\")+filenameINI, i );
				BOOL bResult = DeleteFile(strImageFilename);

				//	delete pov
				strImageFilename.Format(_T("%s%05d.pov"), ((CProteinVistaApp*)AfxGetApp())->m_strBaseScriptMovie+_T("Images\\")+filenameINI, i );
				DeleteFile(strImageFilename);
			}

			//	delete ini
			DeleteFile(strMovieIniFilePath);

			//
			//	modify POVRENDER_QUEUE.INI
			//	
			CString strPOVRAYQueFilename;
			strPOVRAYQueFilename.Format ( "%sImages\\POVRENDER_QUEUE.INI" , ((CProteinVistaApp*)AfxGetApp())->m_strBaseScriptMovie );

			TCHAR fname[MAX_PATH];
			TCHAR ext[MAX_PATH];
			_splitpath(strMovieIniFilePath, NULL, NULL , fname, ext );

			WritePrivateProfileString( CString(fname) + ext, NULL, NULL, strPOVRAYQueFilename);
		}
	}

	OnCancel();
}

BOOL CPovRayMakeMovie::OnInitDialog()
{
	CDialog::OnInitDialog();

	m_listCtrlImageList.InsertColumn(0, _T("Movie Filename"), LVCFMT_LEFT, 100);
	m_listCtrlImageList.InsertColumn(1, _T("POV-RAY Render Finished"), LVCFMT_LEFT, 160);
	m_listCtrlImageList.InsertColumn(2, _T("Movie filename"), LVCFMT_LEFT, 450);

	//	fill up the items.
	CString strPOVRAYQueFilename;
	strPOVRAYQueFilename.Format ( "%sImages\\POVRENDER_QUEUE.INI" , ((CProteinVistaApp*)AfxGetApp())->m_strBaseScriptMovie );

	TCHAR buff[1024*3];
	TCHAR * buffSectionNames;
	GetPrivateProfileSectionNames(buff, 1024*3, strPOVRAYQueFilename);
	buffSectionNames = buff;

	INT32	iItem = 0;
	CString strSection(buffSectionNames);
	while(!strSection.IsEmpty())
	{
		CString strMovieIniFileName = strSection;
		CString strMovieIniFilePath;
		strMovieIniFilePath.Format("%sImages\\%s" , ((CProteinVistaApp*)AfxGetApp())->m_strBaseScriptMovie, strMovieIniFileName );
		CString strMovieName = (strMovieIniFileName.Mid(10)).Left((strMovieIniFileName.Mid(10)).GetLength()-4);

		//	check all rendered.
/*
[Movie]
FileName=rotation
Width=800
Height=600
Fps=10
FilenameFormat=%s%01d.png
NumImages=10
[Frames]
1
1
1
*/
		TCHAR buff[1024*10];
		GetPrivateProfileString(_T("Movie"), _T("FileName"),_T(""), buff , MAX_PATH, strMovieIniFilePath);
		CString filenameINI(buff);

		GetPrivateProfileString(_T("Movie"), _T("FilenameFormat"),_T(""), buff , MAX_PATH, strMovieIniFilePath);
		CString filenameFormatINI(buff);

		GetPrivateProfileString(_T("Movie"), _T("FinalMoviePath"),_T(""), buff , MAX_PATH, strMovieIniFilePath);
		CString filenameMoviePath(buff);
		
		INT32	movieNumImages = GetPrivateProfileInt(_T("Movie"), _T("NumImages"), 0, strMovieIniFilePath);

		//	check all file exist.
		BOOL bAllExist = TRUE;
		for ( int i = 0 ; i < movieNumImages; i++ )
		{
			CString strImageFilename;
			strImageFilename.Format(filenameFormatINI, ((CProteinVistaApp*)AfxGetApp())->m_strBaseScriptMovie+_T("Images\\")+strMovieName, i );

			HANDLE fileExist = CreateFile( strImageFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
			if( INVALID_HANDLE_VALUE == fileExist )
			{
				bAllExist = FALSE;
				break;
			}
			if ( fileExist != INVALID_HANDLE_VALUE ) CloseHandle(fileExist);
		}
		if ( bAllExist == TRUE )
		{	//	all exist
			//	may all rendered.
			m_listCtrlImageList.InsertItem(iItem, strMovieName);
			m_listCtrlImageList.SetItemText(iItem, 1, _T("May All Rendered"));
		}
		else
		{
			//	not all rendered.
			m_listCtrlImageList.InsertItem(iItem, strMovieName);
			m_listCtrlImageList.SetItemText(iItem, 1, _T("Not All Rendered"));
		}

		CString strFinalMoviePath;
		ConvertFinalMoviePath(filenameMoviePath, strFinalMoviePath);

		HANDLE fileExist = CreateFile( strFinalMoviePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
		if( INVALID_HANDLE_VALUE == fileExist )
		{
			m_listCtrlImageList.SetItemText(iItem, 2, _T("No movie file"));
		}
		else
		{
			m_listCtrlImageList.SetItemText(iItem, 2, strFinalMoviePath );
		}
		if ( fileExist != INVALID_HANDLE_VALUE ) CloseHandle(fileExist);

		m_strArrayMovieFilename.Add(strFinalMoviePath);

		//	
		m_strArrayINIFilename.Add(strMovieIniFilePath);

		//	
		iItem ++;

		buffSectionNames += (strSection.GetLength()+1);
		strSection = CString(buffSectionNames);
	}

	return TRUE;  // return TRUE unless you set the focus to a control
	// EXCEPTION: OCX Property Pages should return FALSE
}

BOOL CPovRayMakeMovie::ConvertFinalMoviePath(CString strMoviePath, CString &strFinalMoviePath)
{
	TCHAR drive[MAX_PATH];
	TCHAR dir[MAX_PATH];
	TCHAR fname[MAX_PATH];
	TCHAR ext[MAX_PATH];
	_splitpath(strMoviePath, drive, dir, fname, ext );

	if ( drive[0] != NULL && dir[0] != NULL )
	{
		strFinalMoviePath = CString(strMoviePath);
	}
	else
	{
		strFinalMoviePath.Format(_T("%s%s%s") , ((CProteinVistaApp *)AfxGetApp())->m_strBaseScriptMovie, fname, ext );
	}

	return S_OK;
}